/**
 * Created by Eric.Dou on 3/26/14.
 */
define(function (require, exports, module) {

    var _prefix = "views_", self = this, $ = require('lib/jquery'), comm = require('lib/commons');
    require('lib/plugins/jquery.element.js')($);
    require('lib/dyc/SmartGadget')(self, $);

    exports.depend = function (core) {
        if (typeof(core) !== 'undefined') {
            core.initPage = function (jQuery, options, handlerExport) {
                _init = function () {
                    jQuery(document).ready(function () {
                        jQuery.each(options.views, function (i, data) {
                            var compOption = {};
                            jQuery.extend(compOption, options[_prefix + data]);
                            initComponent(compOption);
                        });
                    });
                };

                if (typeof(handlerExport) == 'undefined') {
                    handlerExport = core;
                }

                if (typeof(handlerExport) != 'undefined') {
                    if (jQuery.isFunction(handlerExport.init)) {
                        handlerExport.init = function () {
                            _init(), handlerExport.init();
                        };
                    } else {
                        handlerExport.init = _init;
                    }
                }

            };
        }
    };
    function hashCode(str) {
        return comm.hash(str);
    }

    function BuilderV2(pch, args) {
        $builder = this;
        this.proChain = pch, this.options = args, this._result = [];
        var seed = 10000, sid = Math.floor(Math.random() * seed);
        this.processHashCode = _hashProcessName(pch);
        this.clear = function () {
            $builder.options = null;
            $builder._result = [];
        };
        this.addData = function (data) {
            console.info("--------------");
            console.log(data);
            $builder.options = data;
        };
        this.load = function (options) {
            if (arguments.length == 1) {
                $builder.clear();
                $builder.addData(options);
            }
            _load();
        };
        this.result = function () {
            return $builder._result;
        }
        function _load() {
            var pch = $builder.proChain, options = $builder.options;
            while (typeof(pch) != 'undefined' && pch != null) {
                act = hasPro(pch, 'value') ? pch['value'] : null;

                if (null != act) {
                    console.info(act);
                    console.info(act.process);
                    if (act.condition || ($.isFunction(act.condition) && act.condition(options))) {
                        if (undefined == act.process) {
                            $builder._result.push({reason: "undefined this method!"});
                        } else {
                            $builder._result.push(act.process(options));
                        }

                    }
                }
                pch = hasPro(pch, 'next') ? pch.next : null;
            }
        }

        function getNextSid() {
            return ++sid;
        }

        function _resetProcess(processChain) {
            if (_verifyFnChange(processChain)) {
                $builder.proChain = processChain;
            }
        }

        this.resetProcess = _resetProcess;

        function _verifyFnChange(pChain) {
            var code = _hashProcessName(pChain);
            return ( $builder.processHashCode == code);
        }

        function _hashProcessName(pChain) {
            var pch = pChain, proNames = [];
            while (typeof(pch) != 'undefined' && pch != null) {
                if (hasPro(pch, 'value') && hasPro(pch.value, 'processName')) {
                    proNames[proNames.length] = pch.value['processName'];
                }
                else {
                    proNames[proNames.length] = "Action_" + getNextSid();
                }
                pch = hasPro(pch, 'next') ? pch.next : null;
            }
            return hashCode(proNames.join('_'));
        }
    }

    function initComponent(options, action) {
        var scopeBuilderHandler = self;
        if (typeof (options.hasCustomerProcesses) != 'undefined') {
            action = options.hasCustomerProcesses; //has customer processes is force property.
            scopeBuilderHandler = options; // the building page role transfer to the page data object.
        }

        var proChain = getActionHandler(options, action);
        console.info(proChain);
        if (typeof(scopeBuilderHandler.builder) == "undefined" || null == scopeBuilderHandler.builder) {
            scopeBuilderHandler.builder = new BuilderV2(proChain, options);
        }
        else {
            //IF you want manager your actions with options value, let action reload like options.
            scopeBuilderHandler.builder.resetProcess(proChain);
            scopeBuilderHandler.builder.addData(options);

        }
        scopeBuilderHandler.builder.load();

        return scopeBuilderHandler.builder.result();
    }

    function getActionHandler(o, a) {
        if (arguments.length >= 2 && typeof(a) != 'undefined') {
            var act = null, tempHandler = {}, top = self.SG.createDefaultAction(), newChain = self.SG.registProcessWithDefaultChain(null, top);
            self.SG.registHandler(tempHandler, top);
            if ($.isFunction(a)) {
                act = self.SG.createAction(a);
                self.SG.registHandler(tempHandler, act);
                self.SG.registProcessWithDefaultChain(newChain, act);
                return newChain;
            }else if ($.isArray(a)) {
                var topChain = newChain;
                $.each(a, function (index, func) {
                    act = exports.findorCreateAction(o,func);
                    if (act != null) {
                        self.SG.registHandler(tempHandler, act);
                        newChain = self.SG.registProcessWithDefaultChain(newChain, act);
                    }
                });
                return topChain;
            }
        }
        //Default return system process chain.
        return self.SG.getChain(o);
    }

    function hasPro(obj, proName) {
        return comm.hasPro(obj, proName);
    }

    exports.register = function (name, action) {
        self.SG.registAction(name, action);
    };

    exports.findOrCreateAction = function(options,funcName)
    {
        var act = null;
        if ($.isFunction(funcName)) {
            act = self.SG.createAction(funcName)
        } else if (typeof(funcName) == "string") {
            if (hasPro(options, funcName)) {
                act = self.SG.createAction(funcName, o[funcName])
            }
            else if (self.SG.hasName(funcName)) {
                console.log("find the action handler from SG : " + funcName);
                act = self.SG.find(funcName);
            }
        }
        return act;
    };

 //   exports.register('wrapWidgetHtml', wrapWidgetHtml);

//   self.SG.registAction('createSubComponts', createSubComponts);
 //   self.SG.registAction('craeteWidgets', craeteWidgets);
 //   self.SG.registAction('addEventListenerfunction', addEventListenerfunction);
});